#include <am.h>
#include <klib.h>
#include <klib-macros.h>
#include <stdarg.h>

#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)

int itoa(int num, char buf[32], int radix) {
	static const char s[] = "0123456789abcdef";
	int n = num, R = radix;
	char *dst = buf;
	if (n < 0) { *dst++ = '-'; n = -n; }
	if (n < 10) {
		*dst++ = s[n]; *dst = 0;
	}
  else {
		char tmp[32], *p = tmp;
		while (n) { *p++ = s[n % R]; n /= R; }
		while (--p != tmp) *dst++ = *p;
		*dst++ = *tmp; *dst = 0;
	}
	return dst-buf;
}

int printf(const char *fmt, ...) {
  static char buf[1024];
  size_t i = 0;
  va_list ap;
  va_start(ap, fmt);
  size_t res = vsprintf(buf, fmt, ap);
  res = res < 1024? res : 1024;
  while (i < res) {
    putch(*(buf + i));
    i++;
  }
  return res;
}

int vsprintf(char *out, const char *fmt, va_list ap) {
  char *o = out;
	const char *f = fmt;
  va_list another;
	va_copy(another, ap);
	while (*f) {
		int n = 1;
		if ('%' != *f) {
			*o = *f;
		}
    else {
			++f;
			switch (*f) {
			case 's':// 字符串
				const char *p = va_arg(ap, char*);
				n = strlen(p);
				memmove(o, p, n);
				break;
			case 'd':
				char buf[32];
				n = itoa(va_arg(ap, int), buf, 10);
				memmove(o, buf, n);
				break;
			default:
				break;
			}
		}
		++f;
		o += n;
	}
	*o = 0;
	va_end(ap);
	return o-out;
}

int sprintf(char *out, const char *fmt, ...) {
	va_list ap;
	va_start(ap, fmt);
  return vsprintf(out, fmt, ap);
}

int snprintf(char *out, size_t n, const char *fmt, ...) {
  panic("Not implemented");
}

int vsnprintf(char *out, size_t n, const char *fmt, va_list ap) {
  panic("Not implemented");
}

#endif
